/* 
Scenic Graphics Library
Copyright (C) 2007 Jouni Tulkki

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USApackage scenic;
*/

package scenic;

import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.Vector;

import scenic.path.Path;
import scenic.path.PathWalker;

class Tesselator {
	private class Walker implements PathWalker
	{
		public Walker() {
		}
		
		public void beginSubPath(boolean isClosed) {
			beginContour(id);			
		}

		public void endSubPath() {
			endContour(id);			
		}
	
		public void lineTo(double x, double y) {
			vertex(id, x, y);			
		}
	}
	
	private class Triangle
	{
		int vertex1;
		boolean edge1;
		int vertex2;
		boolean edge2;
		int vertex3;
		boolean edge3;
	}
	private int id;
	public Vector<Point2D.Double> vertices = new Vector<Point2D.Double>();
	public Vector<Triangle> triangles = new Vector<Triangle>();
	
	public Tesselator(Path path, AffineTransform transform) {
		id = begin();
		path.walk(new Walker(), Util.multiply(transform, AffineTransform.getScaleInstance(8.0, 8.0)));
		end(id);
		id = 0;
	}
	
	public void draw(DrawContext context) {
		context.renderer.tessBegin(context.context);
		
		for(int i = 0; i < vertices.size(); i++) {
			Point2D.Double p = vertices.get(i);
			
			context.renderer.tessVertex(context.context, p.x, p.y);
		}
		for(int i = 0; i < triangles.size(); i++) {
			Triangle t = triangles.get(i);
			
			context.renderer.tessTriangle(context.context, t.vertex1, t.edge1, t.vertex2, t.edge2,
					t.vertex3, t.edge3);
		}
		context.renderer.tessEnd(context.context);
	}
	
	private native int begin();
	private native void end(int id);
	private native void beginContour(int id);
	private native void endContour(int id);
	private native void vertex(int id, double x, double y);
	
	@SuppressWarnings("unused")
	private void addVertex(double x, double y) {
		vertices.add(new Point2D.Double(x, y));
	}
	
	@SuppressWarnings("unused")
	private void addTriangle(int vertex1, boolean edge1, int vertex2, boolean edge2, 
			int vertex3, boolean edge3) {
		Triangle t = new Triangle();
		
		t.vertex1 = vertex1;
		t.edge1 = edge1;
		t.vertex2 = vertex2;
		t.edge2 = edge2;
		t.vertex3 = vertex3;
		t.edge3 = edge3;
		triangles.add(t);
	}
}
